/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package at.tugraz.hidipic.web.util;

import at.tugraz.hidipic.model.*;
import at.tugraz.hidipic.service.DataAccessService;
import at.tugraz.hidipic.web.KDDConstants;
import java.util.*;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.stereotype.Component;

/**
 *
 * @author mario
 */
@Component
public class DataCreationBean {

    @Autowired
    HibernateTemplate hibernateTemplate;
    @Autowired
    DataAccessService dataAccessService;

    @PostConstruct
    public void createData() {
        createGrants();
        createUsers();
        createMethods();
        createProjects();
        createSubProjects();
        //createResults();
        createComments();
        //createInputdata();
    }

    private void createGrants() {
        List<CustomGrantedAuthority> grants = hibernateTemplate.find("from CustomGrantedAuthority");
        if (grants != null && grants.size() > 0) {
            //do nothing
        } else {
            CustomGrantedAuthority userRole = new CustomGrantedAuthority();
            userRole.setAuthority(KDDConstants.USER_ROLE);
            hibernateTemplate.save(userRole);

            CustomGrantedAuthority adminRole = new CustomGrantedAuthority();
            adminRole.setAuthority(KDDConstants.ADMIN_ROLE);
            hibernateTemplate.save(adminRole);

            CustomGrantedAuthority researcherRole = new CustomGrantedAuthority();
            researcherRole.setAuthority(KDDConstants.RESEARCHER_ROLE);
            hibernateTemplate.save(researcherRole);
        }
    }

    private void createUsers() {
        List<User> users = hibernateTemplate.find("from User");
        if (users != null && users.size() > 0) {
            // do nothing
        } else {
            Md5PasswordEncoder md5pe = new Md5PasswordEncoder();
            String pw = md5pe.encodePassword("1234", null);
            String uname = "admin";
            User user = new User();
            user.setUsername(uname);
            user.setPassword(pw);
            user.setEnabled(true);
            user.setAccountNonLocked(true);
            List<CustomGrantedAuthority> newcgas = hibernateTemplate.find("from CustomGrantedAuthority");
            Set<CustomGrantedAuthority> cgasToAdd = new HashSet<CustomGrantedAuthority>(newcgas);
            user.setAuthorities(cgasToAdd);
            hibernateTemplate.save(user);

            Set<CustomGrantedAuthority> cgasToAddR = new HashSet<CustomGrantedAuthority>();

            for (CustomGrantedAuthority c : cgasToAdd) {
                if (!c.getAuthority().equals(KDDConstants.ADMIN_ROLE)) {
                    cgasToAddR.add(c);
                }
            }

            User researcher = new User();
            researcher.setUsername("sample_res");
            researcher.setPassword(pw);
            researcher.setEnabled(true);
            researcher.setAccountNonLocked(true);
            researcher.setAuthorities(cgasToAddR);
            hibernateTemplate.save(researcher);

            User resp1 = new User();
            resp1.setUsername("res_pro1");
            resp1.setPassword(pw);
            resp1.setEnabled(true);
            resp1.setAccountNonLocked(true);
            resp1.setAuthorities(cgasToAddR);
            hibernateTemplate.save(resp1);

            User resp2 = new User();
            resp2.setUsername("res_pro2");
            resp2.setPassword(pw);
            resp2.setEnabled(true);
            resp2.setAccountNonLocked(true);
            resp2.setAuthorities(cgasToAddR);
            hibernateTemplate.save(resp2);

            Set<CustomGrantedAuthority> cgasToAddU = new HashSet<CustomGrantedAuthority>();

            for (CustomGrantedAuthority c : cgasToAdd) {
                if (c.getAuthority().equals(KDDConstants.USER_ROLE)) {
                    cgasToAddU.add(c);
                }
            }

            User suser = new User();
            suser.setUsername("sample_user");
            suser.setPassword(pw);
            suser.setEnabled(true);
            suser.setAccountNonLocked(true);
            suser.setAuthorities(cgasToAddU);
            hibernateTemplate.save(suser);

        }
    }

    private void createMethods() {
        List<Method> methods = hibernateTemplate.find("from Method");
        if (methods != null && methods.size() > 0) {
            // do nothing
        } else {
            Method method = new Method();
            method.setShowName("CART");
            method.setName("CART");
            method.setDescription("This CART implementation (SimpleCART from WEKA), takes one ARFF File as input.<br /><br />*The File has to contain both the traning and test set and has to be named 'train'"
                    + "<br /><br />The 'TrainingSize'-parameter specifies the size of the training set, by default, 50% of the data is used for training. (0.0 - 1.0)"
                    + "<br />The 'Pruning'-parameter specifies if the algorithm should perform pruning or not. It does not do so by default. (y or n)");
            hibernateTemplate.save(method);

            Method meth = new Method();
            meth.setName("C45");
            meth.setShowName("C45");
            meth.setDescription("This C4.5 implementation takes two ARFF Files. <br /><br />* One File has to be named 'train', this is the training set<br />"
                    + "* The second file has to be named 'test', this is the data set the trained classifier will be tested on."
                    + "<br /><br />The 'ConfidenceThreshold'-parameter specifies the confidence threshold for pruning, if pruning is activated, it is 0.25 by default. (0.0 - 0.5)"
                    + "<br />The 'Pruning'-parameter specifies if the algorithm should perform pruning or not. It does not do so by default. (y or n)");
            hibernateTemplate.save(meth);
        }
    }

    private void createProjects() {
        List<Project> projects = hibernateTemplate.find("from Project");
        if (projects != null && projects.size() > 0) {
            // do nothing
        } else {
            List<Method> methods = hibernateTemplate.find("from Method");
            Project project = new Project();
            User admin = hibernateTemplate.get(User.class, "admin");
            project.setCreationDate(new Date());
            project.setProjectLeader(admin);
            project.setCreator(admin);
            project.setName("ClassificationDemo");
            project.setDescription("This is a project for demo purposes. It can be used to test two different classification-methods.");
            project.setMethods(new HashSet<Method>(methods));
            hibernateTemplate.save(project);
        }
    }

    private void createSubProjects() {
        List<SubProject> subprojects = hibernateTemplate.find("from SubProject");
        if (subprojects != null && subprojects.size() > 0) {
            // do nothing
        } else {
            List<Project> projects = hibernateTemplate.find("from Project");
            if (projects != null && projects.size() > 0) {
                User researcher = hibernateTemplate.get(User.class, "sample_res");
                Set<User> userList = new HashSet<User>(hibernateTemplate.find("from User"));
                SubProject subProject = new SubProject();
                subProject.setName("CART");
                subProject.setDescription("Demo-Project for CART");
                subProject.setCreator(researcher);
                subProject.setCreationDate(new Date());
                subProject.setResearchers(new HashSet<User>(dataAccessService.getAllUsersWithLevel(KDDConstants.RESEARCHER_ROLE)));
                subProject.setParent(projects.get(0));
                subProject.setSharedUserList(userList);
                hibernateTemplate.save(subProject);
                SubProject ssubProject = new SubProject();
                ssubProject.setName("C45");
                ssubProject.setDescription("Demo-Project for C45");
                ssubProject.setCreator(researcher);
                ssubProject.setCreationDate(new Date());
                ssubProject.setResearchers(new HashSet<User>(dataAccessService.getAllUsersWithLevel(KDDConstants.RESEARCHER_ROLE)));
                ssubProject.setParent(projects.get(0));
                ssubProject.setSharedUserList(userList);
                hibernateTemplate.save(ssubProject);
            }
        }
    }

    private void createComments() {
        List<Comment> comments = hibernateTemplate.find("from Comment");
        if (comments != null && comments.size() > 0) {
            // do nothing
        } else {
            User researcher = hibernateTemplate.get(User.class, "sample_user");
            List<Project> projects = hibernateTemplate.find("from Project");
            if (projects != null && projects.size() > 0) {
                for (Project p : projects) {
                    Comment c = new Comment();
                    c.setCreator(researcher);
                    c.setCreationDate(new Date());
                    c.setText("This is a test comment.");
                    c.setProject(p);

                    Comment cc = new Comment();
                    cc.setCreator(researcher);
                    cc.setCreationDate(new Date(2012, 5, 12));
                    cc.setText("This is also a test comment.");
                    cc.setProject(p);

                    hibernateTemplate.save(c);
                    hibernateTemplate.save(cc);
                }
            }

            List<SubProject> subProjects = hibernateTemplate.find("from SubProject");
            if (subProjects != null && subProjects.size() > 0) {
                for (SubProject sp : subProjects) {
                    Comment c = new Comment();
                    c.setCreator(researcher);
                    c.setCreationDate(new Date());
                    c.setText("This is a test comment.");
                    c.setSubProject(sp);

                    Comment cc = new Comment();
                    cc.setCreator(researcher);
                    cc.setCreationDate(new Date(2012, 5, 12));
                    cc.setText("This is also a test comment.");
                    cc.setSubProject(sp);

                    hibernateTemplate.save(c);
                    hibernateTemplate.save(cc);
                }
            }
        }
    }

    private void createInputdata() {
        List<InputDataItem> inps = hibernateTemplate.find("from InputDataItem");
        if (inps != null && inps.size() > 0) {
            // do nothing
        } else {
            User admin = hibernateTemplate.get(User.class, "admin");
            if (admin != null) {
                InputDataItem inp = new InputDataItem();
                inp.setCreated(new Date());
                inp.setCreator(admin);
                inp.setName("f-9088240989838096892.arff");
                inp.setTitle("train");
                inp.setUrl("/dynamicimages/" + "f-9088240989838096892.arff");
                inp.setType("text");
                hibernateTemplate.save(inp);

                InputDataItem inp2 = new InputDataItem();
                inp2.setCreated(new Date());
                inp2.setCreator(admin);
                inp2.setName("f-7540534205334927099.arff");
                inp2.setTitle("test");
                inp2.setUrl("/dynamicimages/" + "f-7540534205334927099.arff");
                inp2.setType("text");
                hibernateTemplate.save(inp2);
            }
        }
    }

    private OutputDataItem createRandomOutputData(User u, Result r) {
        OutputDataItem odi = new OutputDataItem();
        UUID uuid = UUID.randomUUID();
        Long randId = uuid.getMostSignificantBits();
        String id = "f" + randId.toString();
        odi.setName(id);
        odi.setTitle("some parametertitle");
        odi.setVal("random value generated");
        odi.setCreator(u);
        odi.setCreated(new Date());
        odi.setResult(r);
        hibernateTemplate.save(odi);
        return odi;
    }

    private Event createEvent(SubProject sp, int t, String text) {
        Event event = new Event();
        event.setCreationDate(new Date());
        event.setSubProject(sp);
        event.setType(t);
        event.setText(text);
        hibernateTemplate.save(event);
        return event;
    }

    private void createResults() {
        List<Result> results = hibernateTemplate.find("from Result");
        if (results != null && results.size() > 0) {
            // do nothing
        } else {
            List<SubProject> subProjects = hibernateTemplate.find("from SubProject");
            List<Method> methods = hibernateTemplate.find("from Method");
            if (subProjects != null && subProjects.size() > 0 && methods != null && methods.size() > 0) {
                for (SubProject sp : subProjects) {
                    User researcher = hibernateTemplate.get(User.class, "sample_res");
                    C45 ca = new C45();
                    ca.setPruning("n");
                    ca.setConfidenceThreshold("0.25");
                    Result result = new Result();
                    result.setSubProject(sp);
                    result.setCreator(researcher);
                    result.setCreationDate(new Date());
                    result.setMethod(methods.get(0));
                    result.setConfig(ca);
                    hibernateTemplate.save(result);
                    createRandomOutputData(researcher, result);
                    createEvent(sp, 0, "Generated Startevent");
                    createEvent(sp, 2, "Generated Endevent");
                    ca.setResult(result);
                    hibernateTemplate.save(ca);

                    CART cca = new CART();
                    cca.setPruning("n");
                    cca.setTrainingSize("0.5");
                    Result rr = new Result();
                    rr.setSubProject(sp);
                    rr.setCreator(researcher);
                    rr.setCreationDate(new Date());
                    rr.setMethod(methods.get(1));
                    rr.setConfig(cca);
                    hibernateTemplate.save(rr);
                    createRandomOutputData(researcher, rr);
                    createEvent(sp, 0, "Generated Startevent");
                    createEvent(sp, 2, "Generated Endevent");
                    cca.setResult(rr);
                    hibernateTemplate.save(cca);

                    CART ccac = new CART();
                    ccac.setPruning("n");
                    ccac.setTrainingSize("0.5");

                    Result rrr = new Result();
                    rrr.setSubProject(sp);
                    rrr.setCreator(researcher);
                    rrr.setCreationDate(new Date());
                    rrr.setMethod(methods.get(0));
                    rrr.setConfig(ccac);
                    hibernateTemplate.save(rrr);
                    createRandomOutputData(researcher, rrr);
                    createEvent(sp, 0, "Generated Startevent");
                    createEvent(sp, 1, "Generated Errorevent");
                    ccac.setResult(rrr);
                    hibernateTemplate.save(ccac);

                    C45 cac = new C45();
                    cac.setPruning("n");
                    cac.setConfidenceThreshold("0.25");

                    Result rrrr = new Result();
                    rrrr.setSubProject(sp);
                    rrrr.setCreator(researcher);
                    rrrr.setCreationDate(new Date());
                    rrrr.setMethod(methods.get(1));
                    rrrr.setConfig(cac);
                    hibernateTemplate.save(rrrr);
                    createRandomOutputData(researcher, rrrr);
                    createEvent(sp, 0, "Generated Startevent");
                    createEvent(sp, 1, "Generated Errorevent");
                    createEvent(sp, 1, "Generated Errorevent");
                    createEvent(sp, 2, "Generated Endevent");
                    cac.setResult(rrrr);
                    hibernateTemplate.save(cac);
                }
            }
        }
    }
}
